//  config_manager.c
//  Progetto Ingegneria del Web
//
//  Created by Andrea Vitale on 15/10/12.
//  Copyright (c) 2012 Andrea Vitale. All rights reserved.

#include "config_manager.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

//Parse config's lines and populare config_manager_t structure
config_manager_t* loadConfigFile(char* path)
{
    FILE* source_file = fopen(path, "r");

    if (source_file != NULL) {
        char buffer[100];
        
        config_manager = malloc(sizeof(config_manager_t));
        
        while (fgets(&buffer[0], 100, source_file) != NULL) {
            if (buffer[0] == '#' || strlen(buffer) == 0)
                continue;
            else
                parseProperty(config_manager, &buffer[0], 100);
        }
        
        fclose(source_file);
        
        return config_manager;
    } else
        return NULL;
}

//Parse single line and populate relative property
void parseProperty(config_manager_t *config_manager, char* buffer, int buffer_size)
{
    char* trimmed_line = trimWhiteSpace(buffer);
    
    //I'll parse buffer line only if it is a valid line and if it contains '=' character.
    if (trimmed_line != NULL && strchr(trimmed_line, '=') != NULL) {
        char* property = trimWhiteSpace(strtok(trimmed_line, "="));
        char* value = trimWhiteSpace(strtok(NULL, "\0"));
        
        if (strcmp(property, "ServerPort") == 0)
            config_manager->port_number = atoi(value);
        else if (strcmp(property, "ServerBacklogSize") == 0)
            config_manager->backlog_size = atoi(value);
        else if (strcmp(property, "DataBufferSize") == 0)
            config_manager->buffer_size = atoi(value);
        else if (strcmp(property, "ServerDocumentRoot") == 0) {
            config_manager->document_root = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->document_root, value);
        } else if (strcmp(property, "LogLevel")  == 0) {
            config_manager->log_level = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->log_level, value);
        } else if (strcmp(property, "LogMaxDimension") == 0) {
            config_manager->log_max_size = atof(value);
        } else if (strcmp(property, "LogErrorLevelPath") == 0) {
            config_manager->log_error_path = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->log_error_path, value);
        } else if (strcmp(property, "LogErrorLevelFileName") == 0) {
            config_manager->log_error_filename = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->log_error_filename, value);
        } else if (strcmp(property, "LogVerboseLevelPath") == 0) {
            config_manager->log_verbose_path = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->log_verbose_path, value);
        } else if (strcmp(property, "LogVerboseLevelFileName") == 0) {
            config_manager->log_verbose_filename = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->log_verbose_filename, value);
        } else if (strcmp(property, "ServerErrorPagesRoot") == 0) {
            config_manager->error_pages_path = malloc(strlen(value)*sizeof(char));
            strcpy(config_manager->error_pages_path, value);
        } else {
            fprintf(stderr, "Unknown property option.\n");
        }
    }
}

//Trimming string
char* trimWhiteSpace(char *str)
{
    char *end;
    
    while(isspace(*str))
        str++;
    
    if(*str == 0)
        return NULL;
    
    end = str + strlen(str) - 1;
    while(end > str && isspace(*end))
        end--;
    
    *(end+1) = '\0';
    
    return str;
}

//Check if all member vars are valorized
int isAValidConfig(config_manager_t config_manager) {
    int values_are_ok, strings_are_ok;
    
    if (config_manager.backlog_size > 0 && config_manager.buffer_size > 0 && config_manager.port_number > 0)
        values_are_ok = 1;
    
    if (config_manager.document_root != NULL && config_manager.log_error_path != NULL && config_manager.log_level != NULL && config_manager.log_verbose_path != NULL)
        strings_are_ok = 1;
    
    if (strings_are_ok == 1 && values_are_ok == 1)
        return 1;
    else
        return 0;
}

//Print config structure
void printConfigProperties()
{
    fprintf(stderr, "Configuration loaded:\n");
    fprintf(stderr, "- SERVER CONFIGURATION.\n");
    fprintf(stderr, "\tSERVER_DOCUMENT_ROOT: %s\n", config_manager->document_root);
    fprintf(stderr, "\tSERVER_PORT_NUMBER: %d\n", config_manager->port_number);
    fprintf(stderr, "\tSERVER_BACKLOG_SIZE: %d\n", config_manager->backlog_size);
    fprintf(stderr, "\tSERVER_DATA_BUFFER_SIZE: %d\n", config_manager->buffer_size);
    fprintf(stderr, "\n");
    fprintf(stderr, "- LOG CONFIGURATION.\n");
    fprintf(stderr, "\tLOG_LEVEL: %s\n", config_manager->log_level);
    fprintf(stderr, "\tLOG_ERROR_PATH: %s\n", config_manager->log_error_path);
    fprintf(stderr, "\tLOG_ERROR_NAME: %s\n", config_manager->log_error_filename);
    fprintf(stderr, "\tLOG_VERBOSE_PATH: %s\n", config_manager->log_verbose_path);
    fprintf(stderr, "\tLOG_VERBOSE_NAME: %s\n", config_manager->log_verbose_filename);
    fprintf(stderr, "\n");
}